<?php

/**
 * \file
 * Classe d'un bloc formulaire d'édition d'un objet.
 */

/**
 * Génération automatique de formulaires d'administration (CRUD).
 */
namespace pilar\Scaffolding /* \cond */ ; /* \endcond */
{

/**
 * Bloc d'édition.
 *
 * \since 28/10/2008
 * \author Matthieu OVIEDO <matthieu.oviedo@gmail.com>
 */
abstract class EditForm extends \pilar\Forms\Form {

/**
 * Membres d'entité présents dans le formulaire.
 *
 * \since 03/12/2008
 */
protected $_entityMembers = array();


/**
 * Valeurs des champs de l'entité.
 *
 * \since 03/12/2008
 */
protected $_entityFieldValues = array();


protected function loadDefaultParams() {
 parent::loadDefaultParams();

 $this->params->define(array(
  'object' => '',  // Objet que l'on veut éditer.
  'memberNames' => array('default' => true),  // Noms des membres à afficher
                                              // dans le formulaire.
  'configs' => array(),  // Configuration de chacun des membres de formulaire.
  'buttonLabel' => '', // Texte du bouton de confirmation.
  'defaultRedirection' => 'getBack'
 ));
}


protected function initialize() {
 if($this->get('buttonLabel') == '') {
  $this->params->buttonLabel = 'Enregistrer les modifications';
 }
 
 if($this->get('object') == '') {
  $this->params->localId .= '_'.$this->get('entity')->get('name');
 } else {
 	$this->params->localId .= '_'.$this->get('object')->entity()->get('name').
 	                          '_'.$this->get('object')->id();
 }

 parent::initialize();
}


protected function load() {
 parent::load();
 
 // Ajout de la redirection après soumission :
  $this->addRedirection(
   new \pilar\Redirections\Redirection(array(
    'name' => 'default',
    'redirection' => $this->get('defaultRedirection')
   ))
  );
  $this->redirection('default')->setContainer($this);

 // Chargement des membres :
  $this->loadMembers();

 // Ajout de l'action en hidden :
  $action = new \pilar\SimpleFormMembers\TextBox(array(
   'name' => '_action',
   'hidden' => true
  ));
  $action->value = 'save';
  $this->appendAtom($action);

 if($this->get('independent')) {
  $this->redirection('default')->append();
  // Ajout du bouton de confirmation :
   $this->appendAtom(
    new \pilar\Forms\Button(array(
     'label' => $this->get('buttonLabel')
    ))
   );
 }
}


protected function actions() {
 parent::actions();

 if($this->postVarValue('_action_value') == 'save') {
  // Chargement des membres depuis le formulaire :
   if($this->loadFromGui() == 'valid') {
    // Cas où le formulaire est valide. On met à jour l'objet :
     $this->get('object')->set($this->_entityFieldValues);
     $this->dealWithObjectValues();
     $this->get('object')->save();
   }
  if ($this->get('independent')) {
   $this->redirection('default')->redirect();
  }
 } else {
  // Initialisation des valeurs des membres à partir de l'objet :
   $this->initializeFormMemberValues();
 }
}


/**
 * Permet de manipuler l'objet avant sa sauvegarde.
 *
 * \since 03/03/2009
 */
protected function dealWithObjectValues() {}


/**
 * Initialise les membres du formulaire à partir de l'objet passé en
 * paramètre.
 *
 * \since 10/02/2009
 */
private function initializeFormMemberValues() {
 $o = $this->get('object');
 foreach($this->_entityMembers as $em) {
  $m = $this->member($em->get('name'));
  $om = $o->__get($em->get('name'));
  foreach($m->fieldNames() as $fn) {
   $v = $em->getFormFieldValueFromObjectMember($om, $fn);
   $m->setValue($v, $fn);
  }
 }
}


/**
 * Charge les membres à partir des noms passés en paramètres et à partir
 * de la modélisation de l'entité.
 *
 * \since 28/10/2008
 **/
private function loadMembers() {
 // Détermination des noms de membres à prendre en compte :
  $names = array(); // Variable de résultat.
  $conf = $this->get('memberNames'); // Alias de code.
  // Sélection par défaut :
   if(!isset($conf['default']) || $conf['default']) {
    foreach($this->get('object')->entity()->members as $m) {
     if($m->get('inForms')) $names[] = $m->get('name');
    }
   }
  // Modifications par soustractions :
   if(isset($conf['sub'])) $names = array_diff($names, $conf['sub']);
  // Modifications par ajout :
   if(isset($conf['add'])) $names = array_merge($names, $conf['add']);
   
 // Chargement des membres de formulaire :
  foreach($names as $name) {
   $this->joinEntityMember($this->get('object')->entity()->member($name));
  }
}


/**
 * Inscrit un membre d'entité au formulaire.
 *
 * \param $m Membre d'entité.
 *
 * \since 02/12/2008
 */
final private function joinEntityMember(\pilar\Entities\Member $m) {
 $this->_entityMembers[] = $m;
 // Alias de code :
  $configs = $this->get('configs');
 // Ajout du membre de formulaire au formulaire :
  $this->appendAtom(
   $this->entityMember2formMember(
    $m,
    (isset($configs[$m->get('name')])
     ?$configs[$m->get('name')]
     :array()
    )
   )
  );
}


/**
 * Instancie un membre de formulaire en fonction d'un membre d'entité et
 * l'ajoute aux membres.
 *
 * \param $m Membre de l'entité à utiliser.
 *
 * \return Membre de formulaire.
 *
 * \since 09/10/2008
 */
protected function entityMember2formMember($m, $conf) {
 return $m->newFormMember($conf);
}


public function loadFromGui() {
 if($this->_status == 'unknown') {
  $s = parent::loadFromGui();
 
  if($s == 'valid') {
   // Récupération des valeurs des champs de données et vérification de leur
   // validité :
    foreach($this->_entityMembers as $em) {
     $m = $this->member($em->get('name'));
     $this->_entityFieldValues[$em->get('name')] = array();
     foreach($em->fields as $fn => $f) {
      $v = $em->getFieldValueFromFormMember($m, $fn);
      if(!$em->acceptsFieldValue($fn, $v)) {
       $m->setStatus('invalid');
       $s = 'invalid';
      }
      $this->_entityFieldValues[$em->get('name')][$fn] = $v;
     }
    }
   }

   return $s;
 } else return $this->_status; 
}


} // Class.

} // Namespace.

?>

